\documentclass[11pt]{ctexart}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{subcaption}
\usepackage[graphicx]{realboxes}
\usepackage{ctex}
\usepackage[a4paper,left=1.25in,right=1.25in,top=1in,bottom=1in]{geometry}

\title{项目作业报告}
\author{刘小川  \\ 学号 3210105317}

\begin{document}
\maketitle
\section{项目设计思路}
本次作业我分了两步完成，第一步是先编写出各类样条的生成方式函数，第二部是我将我的设计应用到各类题目中去。
\subsection{类设计}
\subsubsection{函数类}
本次作业的第一个设计的类为函数类，因为本次需要使用样条来做分析，数值的每段对应的是一定次数的多项式，所以
函数类采用了一种类继承的设计。那么函数类我们只需要设定一些最基本的对象，比如 () 运算符、函数的导数以及二阶导数。
这些对象我们都可以设计为纯虚函数，因为函数类不是我们这次设计的主要目标。函数类的子类，多项式类，需要我们稍作设计。
其私有类包括了多项式的指数以及其各个次数下的系数，由低到高排列。关于多项式类的功能，我把我们需要的功能都设计了进去，这包括了多项式运算符()，多项式加法减法以及乘法，多项式求导及二阶导，还定义了多项式的输出，这里我所用的输出形式为matlab函数语言所满足的形式，方便对输出的数字可以复制到matlab画出图像来。

\subsubsection{Hermite插值类}
当样条次数为3次时，在求得每一个节点区间两个端点的值以及导数值后，就可以做hermite插值了，注意在该项目作业中我只用到了4个插值的Hemite插值法，而我编写的hermite插值适用于各个类型的插值。Hemite插值的算法是是容易实现的，最终在这个类中我设借了make\_poly函数成员，这个函数成员使用来在插值后生成相应的多项式，这个多项式的形式为一般多项式的形式，而非hermite插值法直接的到的那种多项式类型，因此需要对每种次数的项做相加。

\subsubsection{Spline样条}
这也是本次项目设计的最终目标。该类的设计我也采用了类继承的方式，首先其基类为spline，然后就是虚函数，这里对应不同的样条类型，公共的成员是求解solve()和运算符()，求解是利用给定的条件生成每一段的多项式，而运算符()使用来对一个定义域中的x求值。\par
对于P样条，他的私有类成员包括，节点个数N，节点坐标x，插值坐标y，左右的边界条件，以及边界类型，还有一个向量，这个向量用于多项式的储存。下面主要是求解函数的构造，这个就是利用到了课本中的三对角矩阵的构造，通过解出$m_i$，再用hermite插值法来求解出每一段的多项式。\par
需要额外分条件考虑的是样条的次数，以及边界的类型。对于P样条当然只有一次和三次的区别，这个也很容易实现。对与不同的边界类型，其主要影响三对角矩阵的构造以及右边b向量的构造，在编写程序时稍加注意即可。\par
关于B样条的产生，其私有类成员多了系数coef，和b样条基，我们在构造类时会直接构造出B样条的基，其他过程和P样条的求解类似。
\subsection{题目求解分析}
在运行程序时只需输入make run即可。具体的题目是程序开头字母对应相应的题解
\subsubsection{A}
关于A的误差结果我已将其输出到"output/A\_ output.txt"中。从图像中我们可以更直观的观察这个结果，随着N增加曲线拟合明显变得更好。\par

\begin{figure}[h]
	\centering
	\includegraphics[width = 0.45\textwidth]{../plts/A6.png}
	\includegraphics[width = 0.45\textwidth]{../plts/A11.png}
	\caption{N=6和11时插值结果与原图像对比}
\end{figure}

\begin{figure}[h]
	\centering
	\includegraphics[width = 0.45\textwidth]{../plts/A21.png}
	\includegraphics[width = 0.45\textwidth]{../plts/A41.png}
	\caption{N=21和41时插值结果与原图像对比}
\end{figure}

\begin{figure}[h]
	\centering
	\includegraphics[width = 0.6\textwidth]{../plts/A81.png}
	\caption{N=81时插值结果与原图像对比}
\end{figure}


随着N增加我们有中心误差的变化\par


\begin{center}
\begin{tabular}{|c|c|c}
\hline
$N$ & 最大误差 \\
\hline
6 & 0.0934104 \\  
11 & 0.0205289 \\
21 & 0.00316894 \\
41 & 0.00012413 \\
81 &  7.042042e-6 \\
\hline
\end{tabular}
\end{center}

\subsubsection{C}
对于题目C，分别画出二次B样条和三次B样条的图像与精准函数的差别

\begin{figure}[h]
	\centering
	\includegraphics[width = 0.6\textwidth]{../plts/C2.png}
	\caption{二次B样条与精准函数对比图}
\end{figure}

\begin{figure}[h]
	\centering
	\includegraphics[width = 0.6\textwidth]{../plts/C3.png}
	\caption{三次B样条与精准函数对比图}
\end{figure}

可看出三次B样条拟合效果更好，基本消除了runge现象，与精准函数图像十分接近。此外,题目输出在"C\_output.txt"中\par

\subsubsection{D}
对于题目D，计算拟合后在特定点处的误差。有\par
{
\centering\includegraphics[width=0.9\textwidth]{../plts/D1.png}

}\par
在接近插值点时，可以看出误差都很小，三次B样条比二次更小。在插值点处已逼近机器误差。

\subsection{E}
关于编写的程序已经放在plts中，直接展示图片\par
\begin{figure}[h]
	\centering
	\includegraphics[width = 0.45\textwidth]{../plts/E10.png}
	\includegraphics[width = 0.45\textwidth]{../plts/E40.png}	
	\caption{三次B样条与精准函数对比图}
\end{figure}
\begin{figure}[h]
	\centering
	\includegraphics[width = 0.6\textwidth]{../plts/E160.png}
	\caption{三次B样条与精准函数对比图}
\end{figure}
\section{作业总结}
程序运行在project目录下运行make run即可打印出所有输出文件，在*.m下使用matlab可以生成对应的图像，输入make report即可生成本次作业报告。关于本项目的配置，我使用了C++的Eigen库文件进行相关矩阵的求解，Eigen库的配置是在下载了以后直接Cmake编译，并且将该库文件移动到了include文件夹中添加路径，然后有关jsoncpp的配置我是直接用Synaptic Package Manager下载器下载的。
\end{document}